import { ui } from "./../ui/layaMaxUI";
import BlockControl from "./BlockControl";
/**
 * 本示例采用非脚本的方式实现，而使用继承页面基类，实现页面逻辑。在IDE里面设置场景的Runtime属性即可和场景进行关联
 * 相比脚本方式，继承式页面类，可以直接使用页面定义的属性（通过IDE内var属性定义），比如this.tipLbll，this.scoreLbl，具有代码提示效果
 * 建议：如果是页面级的逻辑，需要频繁访问页面内多个元素，使用继承式写法，如果是独立小模块，功能单一，建议用脚本方式实现，比如子弹脚本。
 */
export default class GameUI extends ui.test.TestSceneUI {
	private mat1: Laya.BlinnPhongMaterial;
	private newScene: Laya.Scene3D;
	public static BOX_HEIGHT = 0.5
	public scoreNum: number
	public blockNum: number
	public static SIZE_X
	public static SIZE_Z
	public static instance: GameUI
	private lastBlock: Laya.MeshSprite3D
	private currBlock: Laya.MeshSprite3D
	private meshBox: Laya.Sprite3D
	private camera : Laya.Camera

	constructor() {
		super();
		GameUI.instance = this

		GameUI.SIZE_X = 2.5
		GameUI.SIZE_Z = 2.5
		this.newScene = Laya.stage.addChild(new Laya.Scene3D()) as Laya.Scene3D;

		this.meshBox = new Laya.Sprite3D
		this.newScene.addChild(this.meshBox)
		this.meshBox.transform.rotate(new Laya.Vector3(0, 45, 0), true, false)

		//初始化照相机
		var camera = this.newScene.addChild(new Laya.Camera(0, 0.1, 100)) as Laya.Camera;
		camera.transform.translate(new Laya.Vector3(0, 6, 9.5));
		camera.transform.rotate(new Laya.Vector3(-15, 0, 0), true, false);

		//正交投影属性设置
		camera.orthographic = true
		//正交垂直矩阵距离,控制3D物体远近与显示大小
		camera.orthographicVerticalSize = 10;

			
		this.camera = camera

		//方向光
		var directionLight = new Laya.DirectionLight();
		this.newScene.addChild(directionLight);
		directionLight.color = new Laya.Vector3(0.6, 0.6, 0.6);
		//设置平行光的方向
		var mat = directionLight.transform.worldMatrix;
		mat.setForward(new Laya.Vector3(-1.0, -1.0, -1.0));
		directionLight.transform.worldMatrix = mat;

		this.init()

	}

	public init() {
		this.blockNum = 0
		this.scoreNum = 0
		this.score.text = this.scoreNum + ''
		let box = this.addBox(GameUI.SIZE_X, GameUI.SIZE_Z, new Laya.Vector3(0, -2, 0))
		this.lastBlock = box
		this.meshBox.transform.localPositionY = 0

		Laya.Tween.to(box.transform, { localPositionY: box.transform.localPositionY + 3.5 }, 500, Laya.Ease.backOut, Laya.Handler.create(this, () => {
			this.createNewBlock(new Laya.Vector3(box.transform.localPositionX, box.transform.localPositionY + GameUI.BOX_HEIGHT, box.transform.localPositionZ), GameUI.SIZE_X, GameUI.SIZE_Z)
		}))
	}

	private createNewBlock(localPosition, SIZE_X, SIZE_Z) {
		if (this.blockNum >= 5 && (this.blockNum - 5) % 3 == 0) {
		//相机设置清楚标记,使用固定颜色
		this.camera.clearFlag = Laya.BaseCamera.CLEARFLAG_SOLIDCOLOR;
			//设置背景颜色
			this.camera.clearColor = new Laya.Vector4(Math.random()/2, Math.random()/2, Math.random()/2, 0.5)
			// 下移
			Laya.timer.once(500, this, () => {
				Laya.Tween.to(this.meshBox.transform, { localPositionY: this.meshBox.transform.localPositionY - GameUI.BOX_HEIGHT * 3 }, 500, null, Laya.Handler.create(this, () => {
					this.createNewBlockItem(localPosition, SIZE_X, SIZE_Z)
				}))
			})
		} else {
			// 创建第一个box
			this.createNewBlockItem(localPosition, SIZE_X, SIZE_Z)
		}
	}

	private createNewBlockItem(localPosition, SIZE_X, SIZE_Z) {
		this.currBlock = this.addBox(SIZE_X, SIZE_Z, localPosition)
		this.currBlock.addComponent(BlockControl)
		Laya.stage.once(Laya.Event.CLICK, this, this.onClick)
	}

	private onClick() {
		// block停止运行
		let blockControl = this.currBlock.getComponent(BlockControl) as BlockControl
		blockControl.enabled = false
		let lastShape = (this.lastBlock.getComponent(Laya.PhysicsCollider) as Laya.PhysicsCollider).colliderShape as Laya.BoxColliderShape
		let currShape = (this.currBlock.getComponent(Laya.PhysicsCollider) as Laya.PhysicsCollider).colliderShape as Laya.BoxColliderShape
		// 判断游戏结果
		if (this.blockNum % 2 == 0) {
			// x轴移动
			let width = lastShape.sizeX

			let deltaX = this.currBlock.transform.localPositionX - this.lastBlock.transform.localPositionX
			if (Math.abs(deltaX) >= width) {
				this.reStart()
			}
			else {
				if (Math.abs(deltaX) <= 0.01) {
					// 视为重合
					this.scoreNum += 2
				} else {
					// 切块
					this.scoreNum++
					if (deltaX > 0) {
						// 下box右边界
						let lastBorder_r = this.lastBlock.transform.localPositionX + width / 2
						// 上box 左边界
						let currBorder_l = this.currBlock.transform.localPositionX - width / 2
						// 在下box上面部分长度
						let widthOnBox = lastBorder_r - currBorder_l
						// 剩余部分
						let widthOutBox = width - widthOnBox
						// 当前box缩放 获取当前位置
						let currPos = new Laya.Vector3(lastBorder_r - widthOnBox / 2, this.currBlock.transform.localPositionY, this.currBlock.transform.localPositionZ)
						// 缩放倍率
						let scaleX = widthOnBox / width
						this.currBlock.transform.localPosition = currPos
						this.currBlock.transform.localScale = new Laya.Vector3(scaleX, 1, 1)
						// 创建掉落box
						// 获取位置
						currPos = new Laya.Vector3(lastBorder_r + widthOutBox / 2, this.currBlock.transform.localPositionY, this.currBlock.transform.localPositionZ)
						// 获取size
						let size = new Laya.Vector3(widthOutBox, currShape.sizeY, currShape.sizeZ)
						this.createDownBlock(currPos, size, this.currBlock.meshRenderer.material.albedoColor)

						// 重新添加碰撞盒
						currShape = this.addColliderShape(currShape.sizeX * scaleX, currShape.sizeY, currShape.sizeZ, this.currBlock)
					} else {
						// 下box右边界
						let lastBorder_l = this.lastBlock.transform.localPositionX - width / 2
						// 上box 左边界
						let currBorder_r = this.currBlock.transform.localPositionX + width / 2
						// 在下box上面部分长度
						let widthOnBox = currBorder_r - lastBorder_l
						// 剩余部分
						let widthOutBox = width - widthOnBox
						// 当前box缩放 获取当前位置
						let currPos = new Laya.Vector3(lastBorder_l + widthOnBox / 2, this.currBlock.transform.localPositionY, this.currBlock.transform.localPositionZ)
						// 缩放倍率
						let scaleX = widthOnBox / width
						this.currBlock.transform.localPosition = currPos
						this.currBlock.transform.localScale = new Laya.Vector3(scaleX, 1, 1)
						// 创建掉落box
						// 获取位置
						currPos = new Laya.Vector3(lastBorder_l - widthOutBox / 2, this.currBlock.transform.localPositionY, this.currBlock.transform.localPositionZ)
						// 获取size
						let size = new Laya.Vector3(widthOutBox, currShape.sizeY, currShape.sizeZ)
						this.createDownBlock(currPos, size, this.currBlock.meshRenderer.material.albedoColor)

						// 重新添加碰撞盒
						currShape = this.addColliderShape(currShape.sizeX * scaleX, currShape.sizeY, currShape.sizeZ, this.currBlock)
					}
				}

				this.blockNum++
				this.score.text = this.scoreNum + ''
				this.lastBlock = this.currBlock
				this.createNewBlock(new Laya.Vector3(this.lastBlock.transform.localPositionX, this.lastBlock.transform.localPositionY + GameUI.BOX_HEIGHT, this.lastBlock.transform.localPositionZ), currShape.sizeX, currShape.sizeZ)
			}

		} else {
			// z轴运动
			let width = lastShape.sizeZ
			let deltaZ = this.currBlock.transform.localPositionZ - this.lastBlock.transform.localPositionZ
			if (Math.abs(deltaZ) >= width) {
				this.reStart()
			}
			else {
				if (Math.abs(deltaZ) <= 0.01) {
					// 视为重合
					this.scoreNum += 2
				} else {
					// 切块
					this.scoreNum++
					if (deltaZ > 0) {
						// 下box右边界
						let lastBorder_d = this.lastBlock.transform.localPositionZ + width / 2
						// 上box 左边界
						let currBorder_u = this.currBlock.transform.localPositionZ - width / 2
						// 在下box上面部分长度
						let widthOnBox = lastBorder_d - currBorder_u
						// 剩余部分
						let widthOutBox = width - widthOnBox
						// 当前box缩放 获取当前位置
						let currPos = new Laya.Vector3(this.currBlock.transform.localPositionX, this.currBlock.transform.localPositionY, lastBorder_d - widthOnBox / 2)
						// 缩放倍率
						let scaleZ = widthOnBox / width
						this.currBlock.transform.localPosition = currPos
						this.currBlock.transform.localScale = new Laya.Vector3(1, 1, scaleZ)
						// 创建掉落box
						// 获取位置
						currPos = new Laya.Vector3(this.currBlock.transform.localPositionX, this.currBlock.transform.localPositionY, lastBorder_d + widthOutBox / 2)
						// 获取size
						let size = new Laya.Vector3(currShape.sizeX, currShape.sizeY, widthOutBox)
						this.createDownBlock(currPos, size, this.currBlock.meshRenderer.material.albedoColor)

						// 重新添加碰撞盒
						currShape = this.addColliderShape(currShape.sizeX, currShape.sizeY, currShape.sizeZ * scaleZ, this.currBlock)
					} else {
						// 下box右边界
						let lastBorder_d = this.lastBlock.transform.localPositionZ - width / 2
						// 上box 左边界
						let currBorder_u = this.currBlock.transform.localPositionZ + width / 2
						// 在下box上面部分长度
						let widthOnBox = currBorder_u - lastBorder_d
						// 剩余部分
						let widthOutBox = width - widthOnBox
						// 当前box缩放 获取当前位置
						let currPos = new Laya.Vector3(this.currBlock.transform.localPositionX, this.currBlock.transform.localPositionY, lastBorder_d + widthOnBox / 2)
						// 缩放倍率
						let scaleZ = widthOnBox / width
						this.currBlock.transform.localPosition = currPos
						this.currBlock.transform.localScale = new Laya.Vector3(1, 1, scaleZ)
						// 创建掉落box
						// 获取位置
						currPos = new Laya.Vector3(this.currBlock.transform.localPositionX, this.currBlock.transform.localPositionY, lastBorder_d - widthOutBox / 2)
						// 获取size
						let size = new Laya.Vector3(currShape.sizeX, currShape.sizeY, widthOutBox)
						this.createDownBlock(currPos, size, this.currBlock.meshRenderer.material.albedoColor)
						// 重新添加碰撞盒
						currShape = this.addColliderShape(currShape.sizeX, currShape.sizeY, currShape.sizeZ * scaleZ, this.currBlock)
					}
				}

				this.blockNum++
				this.score.text = this.scoreNum + ''
				this.lastBlock = this.currBlock
				this.createNewBlock(new Laya.Vector3(this.lastBlock.transform.localPositionX, this.lastBlock.transform.localPositionY + GameUI.BOX_HEIGHT, this.lastBlock.transform.localPositionZ), currShape.sizeX, currShape.sizeZ)
			}
		}
	}

	private reStart() {
		Laya.timer.once(1000, this, () => {
			// 是否死亡 游戏重新开始
			for (let i = 0; i < this.meshBox.numChildren;) {
				let child = this.meshBox.getChildAt(i)
				child.destroy()
			}
			this.init()
		})
	}

	private addBox(sizeX, sizeZ, position: Laya.Vector3): Laya.MeshSprite3D {
		//创建盒型MeshSprite3D
		var box = this.meshBox.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(sizeX, GameUI.BOX_HEIGHT, sizeZ))) as Laya.MeshSprite3D;
		//设置材质
		let mat = new Laya.BlinnPhongMaterial()
		mat.albedoColor = new Laya.Vector4(Math.random(), Math.random(), Math.random(), 1)
		box.meshRenderer.material = mat
		box.transform.localPosition = position;
		//创建刚体碰撞器
		// var rigidBody = box.addComponent(Laya.PhysicsCollider) as Laya.PhysicsCollider
		// //创建盒子形状碰撞器
		// var boxShape = new Laya.BoxColliderShape(sizeX, GameUI.BOX_HEIGHT, sizeZ);
		// //设置盒子的碰撞形状
		// rigidBody.colliderShape = boxShape;
		this.addColliderShape(sizeX, GameUI.BOX_HEIGHT, sizeZ, box)
		//设置刚体的质量
		// rigidBody.mass = 10;
		return box
	}

	private createDownBlock(position: Laya.Vector3, size: Laya.Vector3, albedoColor: Laya.Vector4) {
		//创建盒型MeshSprite3D
		var box = this.meshBox.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(size.x, size.y, size.z))) as Laya.MeshSprite3D;
		//设置材质
		let mat = new Laya.BlinnPhongMaterial()
		mat.albedoColor = albedoColor
		box.meshRenderer.material = mat
		box.transform.localPosition = position;
		//创建刚体碰撞器
		var rigidBody = box.addComponent(Laya.Rigidbody3D) as Laya.Rigidbody3D
		//创建盒子形状碰撞器
		var boxShape = new Laya.BoxColliderShape(size.x, size.y, size.z);
		//设置盒子的碰撞形状
		rigidBody.colliderShape = boxShape;
		//设置刚体的质量
		rigidBody.mass = 10;
	}

	private addColliderShape(x, y, z, box: Laya.MeshSprite3D): Laya.BoxColliderShape {
		var boxShape = new Laya.BoxColliderShape(x, y, z);
		var rigidBody = box.getComponent(Laya.PhysicsCollider) as Laya.PhysicsCollider
		if (!rigidBody) rigidBody = box.addComponent(Laya.PhysicsCollider) as Laya.PhysicsCollider
		rigidBody.colliderShape = boxShape;
		return boxShape
	}
}